package com.xinhe.web.service;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.xinhe.web.common.Result;
import com.xinhe.web.entity.*;
import com.xinhe.web.reposity.GoodsPriceRepository;
import com.xinhe.web.reposity.GoodsRepository;
import com.xinhe.web.reposity.GoodsZoneTypeRepository;
import com.xinhe.web.request.GoodsModel;
import com.xinhe.web.request.GoodsPriceModel;
import com.xinhe.web.response.GoodsCollectView;
import com.xinhe.web.response.GoodsShopCollectView;
import com.xinhe.web.response.GoodsView;
import com.xinhe.web.session.UserSessionManager;
import com.xinhe.web.util.Snowflake;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.inject.Provider;
import javax.persistence.EntityManager;
import java.util.*;
import java.util.stream.Collectors;

@Service

public class GoodsService {
    @Autowired
    private GoodsRepository goodsRepository;
    //查询工厂
    private JPAQueryFactory queryFactory;
    @Autowired
    private Provider<EntityManager> entityManager;

    @PostConstruct
    public void init() {
        queryFactory = new JPAQueryFactory(entityManager);
    }

    @Autowired
    UserSessionManager userSessionManager;
    @Autowired
    GoodsZoneTypeRepository goodsZoneTypeRepository;
    @Autowired
    AttachService attachService;
    @Autowired
    GoodsPriceService goodsPriceService;
    @Autowired
    GoodsPriceRepository goodsPriceRepository;

    public QueryResults<GoodsView> pageGoods(int pageNum, int pageSize) {
        QGoods qGoods = QGoods.goods;
        QGoodsPrice qGoodsPrice = QGoodsPrice.goodsPrice;
        BooleanBuilder builder = new BooleanBuilder();
        //builder.and(qGoods.removed.eq(0));
        return queryFactory.select(
                Projections.bean(
                        GoodsView.class,
                        qGoods.sellerUserId,
                        qGoods.fGoodsTypeId,
                        qGoods.id,
                        qGoods.goodsZoneType,
                        qGoods.fGoodsZoneTypeId,
                        qGoods.name,
                        qGoods.iconPath,
                        qGoods.dis,
                        qGoods.price,
                        qGoods.sendAddress,
                        qGoods.freightFee,
                        qGoodsPrice.originalPrice,
                        qGoodsPrice.unit
                )
        ).from(qGoods)
                .leftJoin(qGoodsPrice).on(qGoods.priceId.eq(qGoodsPrice.id))
                .where(builder).offset(pageNum * pageSize).limit(pageSize).fetchResults();
    }

    public Result<Goods> findById(Long goodsId) {
        return Result.ok(goodsRepository.findById(goodsId).get());
    }

    public Result delete(Long goodsId) {
        goodsRepository.deleteById(goodsId);
        return Result.ok();
    }
    @Transactional
    public Result saveGoods(GoodsModel model) {
        Long userId = this.userSessionManager.getUserId();
        //新增
        if (null == model.getId()){
            Goods goods = new Goods();
            goods.setId(Snowflake.generateId());
            goods.setSellerUserId(Long.valueOf(1L));
            goods.setfGoodsTypeId(model.getGoodsTypeId());
            goods.setfGoodsZoneTypeId(model.getGoodsZoneTypeId());
            goods.setName(model.getName());
            goods.setIconPath(model.getName());
            goods.setDis(model.getDis());
            //goods.setPrice();
            //goods.setPriceId();
            //goods.setSpikePrice();
            //goods.setGroupPurchasePrice();
            goods.setSendAddress(model.getSendAddress());
            goods.setRemark(model.getRemark());
            goods.setType("PLATFORM");
            goods.setRemark(model.getRemark());
            goods.setIsHotSales(model.getIsHotSales());
            if (null != model.getGoodsZoneTypeId()) {
                GoodsZoneType goodsZoneType = this.goodsZoneTypeRepository.findById(model.getGoodsZoneTypeId()).get();
                if ("帮扶专区".equals(goodsZoneType.getName())) {
                    goods.setGoodsZoneType(Integer.valueOf(1));
                } else if ("家园优品".equals(goodsZoneType.getName())) {
                    goods.setGoodsZoneType(Integer.valueOf(2));
                } else if ("链动专区".equals(goodsZoneType.getName())) {
                    goods.setGoodsZoneType(Integer.valueOf(3));
                } else {
                    goods.setGoodsZoneType(Integer.valueOf(4));
                }
            } else {
                goods.setGoodsZoneType(Integer.valueOf(0));
            }
            //保存图片信息
            this.attachService.updateAttachByBusinessIdAndAttachIds(goods.getId(), model.getAttachIds());
            //保存商品价格详情列表，第一次新增Goods时商品价格详情列表一定是新增
            for (int i = 0; i < model.getGoodsPriceList().size(); i++){
                GoodsPriceModel goodsPriceModel = model.getGoodsPriceList().get(i);
                GoodsPrice goodsPrice = new GoodsPrice();
                goodsPrice.setId(Snowflake.generateId());
                goodsPrice.setGoodsId(goods.getId());
                goodsPrice.setGroupPurchasePrice(goodsPriceModel.getGroupPurchasePrice());
                goodsPrice.setSeckillPrice(goodsPriceModel.getSeckillPrice());
                goodsPrice.setPrice(goodsPriceModel.getPrice());
                goodsPrice.setOriginalPrice(goodsPriceModel.getOriginalPrice());
                goodsPrice.setUnit(goodsPriceModel.getUnit());
                goodsPrice.setName(goodsPriceModel.getName());
                //第一个商品规格的相关价格，放到goods上
                if (i == 0) {
                    goods.setPrice(goodsPriceModel.getPrice());
                    goods.setPriceId(goodsPrice.getId());
                    goods.setSpikePrice(goodsPrice.getSeckillPrice());
                    goods.setGroupPurchasePrice(goodsPrice.getGroupPurchasePrice());
                }
                goodsPriceRepository.save(goodsPrice);
            }
            //保存商品
            this.goodsRepository.save(goods);
        }else {
            //修改
            Optional<Goods> goodsOptional = goodsRepository.findById(model.getId());
            if (!goodsOptional.isPresent()){
                return Result.failed(3030,"修改的商品不存在");
            }
            Goods goods = goodsOptional.get();
            goods.setSellerUserId(userId);
            goods.setfGoodsTypeId(model.getGoodsTypeId());
            goods.setfGoodsZoneTypeId(model.getGoodsZoneTypeId());
            goods.setName(model.getName());
            goods.setIconPath(model.getName());
            goods.setDis(model.getDis());
            //goods.setPrice();
            //goods.setPriceId();
            //goods.setSpikePrice();
            //goods.setGroupPurchasePrice();
            goods.setSendAddress(model.getSendAddress());
            goods.setRemark(model.getRemark());
            goods.setType("PLATFORM");
            goods.setRemark(model.getRemark());
            goods.setIsHotSales(model.getIsHotSales());
            if (null != model.getGoodsZoneTypeId()) {
                GoodsZoneType goodsZoneType = this.goodsZoneTypeRepository.findById(model.getGoodsZoneTypeId()).get();
                if ("帮扶专区".equals(goodsZoneType.getName())) {
                    goods.setGoodsZoneType(Integer.valueOf(1));
                } else if ("家园优品".equals(goodsZoneType.getName())) {
                    goods.setGoodsZoneType(Integer.valueOf(2));
                } else if ("链动专区".equals(goodsZoneType.getName())) {
                    goods.setGoodsZoneType(Integer.valueOf(3));
                } else {
                    goods.setGoodsZoneType(Integer.valueOf(4));
                }
            } else {
                goods.setGoodsZoneType(Integer.valueOf(0));
            }
            //保存图片信息,注意可能删除了一部分，添加了一部分
            this.attachService.updateAttachByBusinessIdAndAttachIds(goods.getId(), model.getAttachIds());
            //保存商品价格详情列表,注意可能删除了一部分，添加了一部分，修改了一部分
            //查询商品下面所有的商品规格详情列表，放到map里面，只要修改列表id再map中是有的就代表是没有删除，需要修改的。剔除掉，剩下map中的就是需要删除的
            List<GoodsPrice> goodsPrices = this.goodsPriceRepository.findGoodsPrice(goods.getId());
            Map<Long, GoodsPrice> map = new HashMap<>();
            if (CollectionUtils.isNotEmpty(goodsPrices)) {
                map = (Map<Long, GoodsPrice>)goodsPrices.stream().collect(Collectors.toMap(GoodsPrice::getId, goodsPrice -> goodsPrice));
            }
            for (int i = 0; i < model.getGoodsPriceList().size(); i++){
                GoodsPriceModel goodsPriceModel = model.getGoodsPriceList().get(i);
                //add
                if (Objects.isNull(goodsPriceModel.getId())){
                    GoodsPrice goodsPrice = new GoodsPrice();
                    goodsPrice.setId(Snowflake.generateId());
                    goodsPrice.setGoodsId(goods.getId());
                    goodsPrice.setGroupPurchasePrice(goodsPriceModel.getGroupPurchasePrice());
                    goodsPrice.setSeckillPrice(goodsPriceModel.getSeckillPrice());
                    goodsPrice.setPrice(goodsPriceModel.getPrice());
                    goodsPrice.setOriginalPrice(goodsPriceModel.getOriginalPrice());
                    goodsPrice.setUnit(goodsPriceModel.getUnit());
                    goodsPrice.setName(goodsPriceModel.getName());
                    if (i == 0) {
                        goods.setPrice(goodsPriceModel.getPrice());
                        goods.setPriceId(goodsPrice.getId());
                        goods.setSpikePrice(goodsPrice.getSeckillPrice());
                        goods.setGroupPurchasePrice(goodsPrice.getGroupPurchasePrice());
                    }
                    goodsPriceRepository.save(goodsPrice);
                }else {//update
                    Optional<GoodsPrice> goodsPriceOptional = goodsPriceRepository.findById(goodsPriceModel.getId());
                    if (!goodsPriceOptional.isPresent()){
                        return Result.failed(3031,"修改的商品规格详情不存在");
                    }
                    GoodsPrice goodsPrice = map.get(goodsPriceModel.getId());
                    if (goodsPrice != null) {
                        map.remove(goodsPriceModel.getId());
                    }
                    goodsPrice.setGroupPurchasePrice(goodsPriceModel.getGroupPurchasePrice());
                    goodsPrice.setSeckillPrice(goodsPriceModel.getSeckillPrice());
                    goodsPrice.setPrice(goodsPriceModel.getPrice());
                    goodsPrice.setOriginalPrice(goodsPriceModel.getOriginalPrice());
                    goodsPrice.setUnit(goodsPriceModel.getUnit());
                    goodsPrice.setName(goodsPriceModel.getName());
                    if (i == 0) {
                        goods.setPrice(goodsPriceModel.getPrice());
                        goods.setPriceId(goodsPrice.getId());
                        goods.setSpikePrice(goodsPrice.getSeckillPrice());
                        goods.setGroupPurchasePrice(goodsPrice.getGroupPurchasePrice());
                    }
                    goodsPriceRepository.saveAndFlush(goodsPrice);
                }
            }
            //map剩余的都是需要删除的
            if (map.keySet().size() > 0) {
                Set<Long> collect = map.values().stream().map(GoodsPrice::getId).collect(Collectors.toSet());
                this.goodsPriceRepository.deleteByIdIn(collect);
            }
            //保存商品
            this.goodsRepository.saveAndFlush(goods);
        }
        return Result.ok();
    }

    @Transactional
    public Result saveSellerGoods(GoodsModel model) {
        Long userId = this.userSessionManager.getUserId();
        Goods goods = new Goods();
        BeanUtils.copyProperties(model, goods);
        goods.setId(Snowflake.generateId());
        goods.setType("SELLER");
        goods.setSellerUserId(userId);
        goods.setRemark(model.getRemark());
        this.attachService.updateAttachByBusinessIdAndAttachIds(goods.getId(), model.getAttachIds());
        this.goodsPriceService.saveGoodsPrice(model.getGoodsPriceList(), goods);
        if (null != model.getGoodsZoneTypeId()) {
            GoodsZoneType goodsZoneType = (GoodsZoneType)this.goodsZoneTypeRepository.findById(model.getGoodsZoneTypeId()).get();
            if ("帮扶专区".equals(goodsZoneType.getName())) {
                goods.setGoodsZoneType(Integer.valueOf(1));
            } else if ("家园优品".equals(goodsZoneType.getName())) {
                goods.setGoodsZoneType(Integer.valueOf(2));
            } else if ("链动专区".equals(goodsZoneType.getName())) {
                goods.setGoodsZoneType(Integer.valueOf(3));
            } else {
                goods.setGoodsZoneType(Integer.valueOf(4));
            }
        } else {
            goods.setGoodsZoneType(Integer.valueOf(0));
        }
        this.goodsRepository.saveAndFlush(goods);
        return Result.ok();
    }

    public QueryResults<GoodsView> pageGoodsBySeller(Long sellerUserId,int pageNum, int pageSize) {
        QGoods qGoods = QGoods.goods;
        QGoodsPrice qGoodsPrice = QGoodsPrice.goodsPrice;
        BooleanBuilder builder = new BooleanBuilder();
        //builder.and(qGoods.removed.eq(0));
        if (Objects.isNull(sellerUserId)){
            builder.and(qGoods.sellerUserId.eq(sellerUserId));
        }
        return queryFactory.select(
                        Projections.bean(
                                GoodsView.class,
                                qGoods.sellerUserId,
                                qGoods.fGoodsTypeId,
                                qGoods.id,
                                qGoods.goodsZoneType,
                                qGoods.fGoodsZoneTypeId,
                                qGoods.name,
                                qGoods.iconPath,
                                qGoods.dis,
                                qGoods.price,
                                qGoods.sendAddress,
                                qGoods.freightFee,
                                qGoodsPrice.originalPrice,
                                qGoodsPrice.unit
                        )
                ).from(qGoods)
                .leftJoin(qGoodsPrice).on(qGoods.priceId.eq(qGoodsPrice.id))
                .where(builder).offset(pageNum * pageSize).limit(pageSize).fetchResults();
    }

    public Result findByUserCollect() {
        List<GoodsShopCollectView> list = new ArrayList<>();
        Long userId = this.userSessionManager.getUserId();
        QGoods qGoods = QGoods.goods;
        QSellerShop qSellerShop = QSellerShop.sellerShop;
        //QOperatemark qOperatemark = QGoodsPrice.goodsPrice;
        BooleanBuilder builder = new BooleanBuilder();
        //builder.and(qGoods.removed.eq(0));
        /*if (Objects.isNull(userId)){
            builder.and(qOperatemark.userId.eq(userId));
        }*/
        List<GoodsCollectView> goodsCollectViews = queryFactory.select(
                        Projections.bean(
                                GoodsCollectView.class,
                                qGoods.sellerUserId,
                                qGoods.fGoodsTypeId,
                                qGoods.id,
                                qGoods.goodsZoneType,
                                qGoods.fGoodsZoneTypeId,
                                qGoods.name,
                                qGoods.iconPath,
                                qGoods.dis,
                                qGoods.price,
                                qGoods.sendAddress,
                                qGoods.freightFee,
                                qSellerShop.name.as("sellerName"),
                                qSellerShop.iconPath.as("sellerIconPath")
                        )
                ).from(qGoods)
                .leftJoin(qSellerShop).on(qGoods.sellerUserId.eq(qSellerShop.fUserId))
                .where(builder).fetch();
        if (CollectionUtils.isNotEmpty(goodsCollectViews)) {
            Map<Long, List<GoodsCollectView>> collect = (Map<Long, List<GoodsCollectView>>)goodsCollectViews.stream().collect(Collectors.groupingBy(GoodsCollectView::getSellerUserId));
            for (Map.Entry<Long, List<GoodsCollectView>> longListEntry : collect.entrySet()) {
                Long sellerUserId = longListEntry.getKey();
                GoodsCollectView goodsCollectView = ((List<GoodsCollectView>)longListEntry.getValue()).get(0);
                GoodsShopCollectView view = new GoodsShopCollectView();
                view.setSellerName(goodsCollectView.getSellerName());
                view.setSellerIconPath(goodsCollectView.getIconPath());
                view.setSellerUserId(sellerUserId);
                view.setGoodsCollectViews(longListEntry.getValue());
                list.add(view);
            }
        }
        return Result.ok(list);
    }

}
